import { EventEmitter } from 'events';
import { SSEService } from './SSEService';
import { WebSocketService } from './WebSocketService';
import { Server } from 'socket.io';

export interface ConnectionInfo {
  deviceId: string;
  sseConnected: boolean;
  wsConnected: boolean;
  capabilities: string[];
  preferredProtocol: 'sse' | 'ws' | 'hybrid';
  lastActivity: number;
}

export interface Message {
  id: string;
  type: string;
  data: any;
  timestamp: number;
  source: string;
  target?: string | string[];
  priority?: 'critical' | 'high' | 'normal' | 'low';
}

export class HybridConnectionManager extends EventEmitter {
  private sseService: SSEService;
  private wsService: WebSocketService;
  private connectionMap: Map<string, ConnectionInfo> = new Map();
  private messageQueue: Map<string, Message[]> = new Map();
  private maxQueueSize = 50;

  constructor(io: Server) {
    super();
    this.sseService = new SSEService();
    this.wsService = new WebSocketService(io);
    
    this.setupEventHandlers();
  }

  // 设置事件处理器
  private setupEventHandlers(): void {
    // WebSocket事件转发
    this.wsService.on('device:register', (data: any) => {
      this.handleDeviceRegister(data);
    });

    this.wsService.on('pairing:generate-code', (data: any) => {
      this.handleGeneratePairingCode(data);
    });

    this.wsService.on('pairing:use-code', (data: any) => {
      this.handleUsePairingCode(data);
    });

    this.wsService.on('voice:send-text', (data: any) => {
      this.handleVoiceSendText(data);
    });

    this.wsService.on('voice:recognize', (data: any) => {
      this.handleVoiceRecognize(data);
    });

    this.wsService.on('voice:stream/start', (data: any) => {
      this.handleVoiceStreamStart(data);
    });

    this.wsService.on('voice:stream/data', (data: any) => {
      this.handleVoiceStreamData(data);
    });

    this.wsService.on('voice:stream/end', (data: any) => {
      this.handleVoiceStreamEnd(data);
    });

    this.wsService.on('device:get-list', (data: any) => {
      this.handleGetDeviceList(data);
    });

    this.wsService.on('device:pair', (data: any) => {
      this.handleDevicePair(data);
    });

    this.wsService.on('device:get-pairing-status', (data: any) => {
      this.handleGetPairingStatus(data);
    });
  }

  // 智能连接选择
  async establishConnection(deviceId: string, capabilities: string[], protocol?: 'sse' | 'ws' | 'hybrid'): Promise<ConnectionInfo> {
    const connectionInfo: ConnectionInfo = {
      deviceId,
      sseConnected: false,
      wsConnected: false,
      capabilities,
      preferredProtocol: protocol || this.determinePreferredProtocol(capabilities),
      lastActivity: Date.now()
    };

    // 根据设备能力选择连接方式
    switch (connectionInfo.preferredProtocol) {
      case 'sse':
        connectionInfo.sseConnected = true;
        break;
      
      case 'ws':
        connectionInfo.wsConnected = true;
        break;
      
      case 'hybrid':
        connectionInfo.sseConnected = true;
        connectionInfo.wsConnected = true;
        break;
    }

    this.connectionMap.set(deviceId, connectionInfo);
    
    // 发送离线消息
    this.sendOfflineMessages(deviceId);
    
    console.log(`混合连接建立: ${deviceId} (协议: ${connectionInfo.preferredProtocol})`);
    return connectionInfo;
  }

  // 根据设备能力确定首选协议
  private determinePreferredProtocol(capabilities: string[]): 'sse' | 'ws' | 'hybrid' {
    const hasVoiceStreaming = capabilities.includes('voice-streaming');
    const hasRealTimePairing = capabilities.includes('real-time-pairing');
    const isMobile = capabilities.includes('mobile');
    const isExtension = capabilities.includes('browser-extension');

    // 移动端：优先SSE，需要语音流时使用混合
    if (isMobile) {
      return hasVoiceStreaming ? 'hybrid' : 'sse';
    }

    // 浏览器扩展：主要SSE，少量WebSocket
    if (isExtension) {
      return 'sse';
    }

    // 桌面端：根据功能需求选择
    if (hasVoiceStreaming || hasRealTimePairing) {
      return 'hybrid';
    }

    return 'sse';
  }

  // 统一消息发送接口
  sendMessage(message: Message): void {
    // 记录消息
    this.logMessage(message);
    
    // 根据目标类型分发
    if (message.target) {
      this.sendToTargets(message);
    } else {
      this.broadcast(message);
    }
  }

  // 发送到特定目标
  private sendToTargets(message: Message): void {
    const targets = Array.isArray(message.target) ? message.target : [message.target];
    
    targets.forEach(targetId => {
      const connectionInfo = this.connectionMap.get(targetId || '');
      
      if (connectionInfo) {
        // 根据消息类型和连接状态选择传输方式
        const transportMethod = this.selectTransportMethod(message, connectionInfo);
        
        switch (transportMethod) {
          case 'sse':
            if (connectionInfo.sseConnected) {
              this.sseService.sendToDevice(targetId || '', message.type, message.data);
            }
            break;
          
          case 'ws':
            if (connectionInfo.wsConnected) {
              this.wsService.sendToDevice(targetId || '', message.type, message.data);
            }
            break;
          
          case 'both':
            // 重要消息同时通过两种方式发送
            if (connectionInfo.sseConnected) {
              this.sseService.sendToDevice(targetId || '', message.type, message.data);
            }
            if (connectionInfo.wsConnected) {
              this.wsService.sendToDevice(targetId || '', message.type, message.data);
            }
            break;
        }
        
        connectionInfo.lastActivity = Date.now();
      } else {
        // 设备离线，缓存消息
        this.queueMessage(targetId || '', message);
      }
    });
  }

  // 广播消息
  private broadcast(message: Message): void {
    this.sseService.broadcast(message.type, message.data);
    this.wsService.broadcast(message.type, message.data);
  }

  // 根据消息类型选择传输方式
  private selectTransportMethod(message: Message, connectionInfo: ConnectionInfo): 'sse' | 'ws' | 'both' {
    const messageType = message.type;
    
    // 语音流数据：必须WebSocket
    if (messageType.startsWith('voice:stream')) {
      return 'ws';
    }
    
    // 实时配对协商：需要WebSocket
    if (messageType.startsWith('pairing:negotiate')) {
      return 'ws';
    }
    
    // 语音识别结果：优先SSE，备选WebSocket
    if (messageType === 'voice:result') {
      return connectionInfo.sseConnected ? 'sse' : 'ws';
    }
    
    // 文字推送：优先SSE
    if (messageType === 'text:receive') {
      return connectionInfo.sseConnected ? 'sse' : 'ws';
    }
    
    // 系统消息：SSE
    if (messageType.startsWith('system:')) {
      return 'sse';
    }
    
    // 心跳检测：WebSocket
    if (messageType === 'heartbeat') {
      return 'ws';
    }
    
    // 默认：SSE
    return 'sse';
  }

  // 离线消息队列
  private queueMessage(deviceId: string, message: Message): void {
    if (!this.messageQueue.has(deviceId)) {
      this.messageQueue.set(deviceId, []);
    }
    
    const queue = this.messageQueue.get(deviceId)!;
    queue.push(message);
    
    // 限制队列大小
    if (queue.length > this.maxQueueSize) {
      queue.shift();
    }
  }

  // 发送离线消息
  private sendOfflineMessages(deviceId: string): void {
    const messages = this.messageQueue.get(deviceId) || [];
    if (messages.length > 0) {
      console.log(`发送 ${messages.length} 条离线消息到设备 ${deviceId}`);
      messages.forEach(message => {
        this.sendMessage(message);
      });
      this.messageQueue.delete(deviceId);
    }
  }

  // 设备上线时发送离线消息
  onDeviceOnline(deviceId: string): void {
    this.sendOfflineMessages(deviceId);
  }

  // 记录消息
  private logMessage(message: Message): void {
    console.log(`消息发送: ${message.type} -> ${message.target || 'broadcast'} (优先级: ${message.priority || 'normal'})`);
  }

  // 获取连接信息
  getConnectionInfo(deviceId: string): ConnectionInfo | undefined {
    return this.connectionMap.get(deviceId);
  }

  // 检查设备是否有连接
  hasConnection(deviceId: string): boolean {
    const connectionInfo = this.connectionMap.get(deviceId);
    return connectionInfo ? (connectionInfo.sseConnected || connectionInfo.wsConnected) : false;
  }

  // 断开设备连接
  disconnectDevice(deviceId: string): void {
    const connectionInfo = this.connectionMap.get(deviceId);
    if (connectionInfo) {
      if (connectionInfo.sseConnected) {
        const sseConnections = this.sseService.getDeviceConnections(deviceId);
        sseConnections.forEach(clientId => {
          this.sseService.disconnect(clientId);
        });
      }
      
      if (connectionInfo.wsConnected) {
        const wsConnections = this.wsService.getDeviceConnections(deviceId);
        wsConnections.forEach(socketId => {
          this.wsService.removeClient(socketId);
        });
      }
      
      this.connectionMap.delete(deviceId);
      console.log(`设备连接断开: ${deviceId}`);
    }
  }

  // 获取连接统计
  getConnectionStats() {
    const sseStats = this.sseService.getConnectionStats();
    const wsStats = this.wsService.getConnectionStats();
    
    return {
      totalDevices: this.connectionMap.size,
      sse: sseStats,
      websocket: wsStats,
      queuedMessages: Array.from(this.messageQueue.entries()).map(([deviceId, messages]) => ({
        deviceId,
        messageCount: messages.length
      }))
    };
  }

  // 清理过期连接
  cleanup(): void {
    this.sseService.cleanup();
    this.wsService.cleanup();
    
    // 清理过期的连接信息
    const now = Date.now();
    const expiredDevices: string[] = [];
    
    this.connectionMap.forEach((info, deviceId) => {
      if (now - info.lastActivity > 600000) { // 10分钟超时
        expiredDevices.push(deviceId);
      }
    });
    
    expiredDevices.forEach(deviceId => {
      this.disconnectDevice(deviceId);
    });
    
    if (expiredDevices.length > 0) {
      console.log(`清理了 ${expiredDevices.length} 个过期的设备连接`);
    }
  }

  // 事件处理器转发
  private handleDeviceRegister(data: any): void {
    this.emit('device:register', data);
  }

  private handleGeneratePairingCode(data: any): void {
    this.emit('pairing:generate-code', data);
  }

  private handleUsePairingCode(data: any): void {
    this.emit('pairing:use-code', data);
  }

  private handleVoiceSendText(data: any): void {
    this.emit('voice:send-text', data);
  }

  private handleVoiceRecognize(data: any): void {
    this.emit('voice:recognize', data);
  }

  private handleVoiceStreamStart(data: any): void {
    this.emit('voice:stream/start', data);
  }

  private handleVoiceStreamData(data: any): void {
    this.emit('voice:stream/data', data);
  }

  private handleVoiceStreamEnd(data: any): void {
    this.emit('voice:stream/end', data);
  }

  private handleGetDeviceList(data: any): void {
    this.emit('device:get-list', data);
  }

  private handleDevicePair(data: any): void {
    this.emit('device:pair', data);
  }

  private handleGetPairingStatus(data: any): void {
    this.emit('device:get-pairing-status', data);
  }

  // 获取SSE服务实例
  getSSEService(): SSEService {
    return this.sseService;
  }

  // 获取WebSocket服务实例
  getWebSocketService(): WebSocketService {
    return this.wsService;
  }
} 